package com.colorfruit.admin.business.service.impl;
import java.util.Date;

import com.colorfruit.admin.business.dao.*;
import com.colorfruit.admin.business.service.PurchaseService;
import com.colorfruit.admin.pojo.constant.CommonConstant;
import com.colorfruit.admin.pojo.entity.*;
import com.colorfruit.admin.pojo.enums.AddressTypeEnum;
import com.colorfruit.admin.pojo.enums.ErrorCodeEnum;
import com.colorfruit.admin.pojo.enums.StatusEnum;
import com.colorfruit.admin.pojo.vo.payorder.PayOrderItemVo;
import com.colorfruit.admin.pojo.vo.purchase.PurchaseDetailInfoVo;
import com.colorfruit.admin.pojo.vo.purchase.PurchaseTotalInfoVo;
import com.colorfruit.framework.common.util.BusinessUtil;
import com.colorfruit.framework.common.util.DataValidateUtil;
import com.colorfruit.framework.model.pojo.BaseResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
@Transactional
public class PurchaseServiceImpl implements PurchaseService {

    @Autowired
    PurchaseTotalInfoMapper purchaseTotalInfoMapper;

    @Autowired
    PurchaseDetailInfoMapper purchaseDetailInfoMapper;

    @Autowired
    PayBusinessOrderMapper payBusinessOrderMapper;

    @Autowired
    PayBusinessOrderItemMapper payBusinessOrderItemMapper;

    @Autowired
    GlobalProcessionControlMapper globalProcessionControlMapper;

    @Autowired
    FoundationUserReceiveAddressMapper foundationUserReceiveAddressMapper;

    @Autowired
    PurchaseTotalAddressInfoMapper purchaseTotalAddressInfoMapper;

    @Autowired
    FoundationSysUserMapper foundationSysUserMapper;

    @Autowired
    LogicTransportInfoMapper logicTransportInfoMapper;

    @Autowired
    FoundationPickGoodsAddressMapper foundationPickGoodsAddressMapper;

    @Autowired
    PurchasePriceCountMapper purchasePriceCountMapper;

    @Autowired
    ConfigCommonMapper configCommonMapper;

    @Override
    public BaseResult countPurchaseOrder() {
        GlobalProcessionControl recentProcession = globalProcessionControlMapper.getRecentProcession();
        log.info("[service] [IN] countPurchaseOrder param : recentProcession = {}", recentProcession.toString());
        List<PayBusinessOrder> payBusinessOrders = payBusinessOrderMapper.selectBusinessListByGlobalId(recentProcession.getId());
        log.info("countPurchaseOrder 总订单个数 = {}", payBusinessOrders.size());
        //1. 统计各个产品数量
        //1.1 分组
        Map<Long, Integer> productMap = new HashMap<>();
        for (PayBusinessOrder payBusinessOrder : payBusinessOrders) {
            List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(payBusinessOrder.getBusinessOrderNo());
            for (PayOrderItemVo payOrderItemVo : payOrderItemVos) {
                Integer productNum = productMap.get(payOrderItemVo.getProductId());
                if (DataValidateUtil.verifyInteger(productNum)){
                    productNum  = productNum + payOrderItemVo.getItemProductNum();
                    productMap.put(payOrderItemVo.getProductId(), productNum);
                }else {
                    productMap.put(payOrderItemVo.getProductId(), payOrderItemVo.getItemProductNum());
                }
            }
        }
        log.info("countPurchaseOrder 总产品个数 = {}", productMap.size());
        //1.2 插入
        for (Long productId : productMap.keySet()){
            PurchaseTotalInfo purchaseTotalInfo = new PurchaseTotalInfo();
            purchaseTotalInfo.setGlobalControlId(recentProcession.getId());
            purchaseTotalInfo.setProductId(productId);
            purchaseTotalInfo.setRecordStatus(StatusEnum.EFFECTIVE_STATUS.getStatusCode());
            purchaseTotalInfo.setNeedPurchaseNumber(productMap.get(productId));
            purchaseTotalInfo.setAlreadyPurchaseNumber(0);
            purchaseTotalInfo.setCreateTime(new Date());
            purchaseTotalInfo.setUpdateTime(new Date());
            purchaseTotalInfoMapper.insert(purchaseTotalInfo);
        }

        //2. 统计各个地址需发货的产品数量
        Map<String, Integer> productAddressMap = new HashMap<>();
        for (PayBusinessOrder payBusinessOrder : payBusinessOrders) {
            Long pickAddressId;
            if (payBusinessOrder.getAddressType() == AddressTypeEnum.PERSONAL_ADDRESS.getCode()){
                FoundationUserReceiveAddress foundationUserReceiveAddress = foundationUserReceiveAddressMapper.selectByPrimaryKey(payBusinessOrder.getReceiveAddressId());
                pickAddressId = foundationUserReceiveAddress.getPickerAddressId();
            }else {
                pickAddressId = payBusinessOrder.getReceiveAddressId();
            }
            List<PayOrderItemVo> payOrderItemVos = payBusinessOrderItemMapper.selectOrderItemList(payBusinessOrder.getBusinessOrderNo());
            for (PayOrderItemVo payOrderItemVo : payOrderItemVos) {
                Long productId = payOrderItemVo.getProductId();
                String addressProductKey = "" + pickAddressId + "_" + productId;
                Integer productNum = productAddressMap.get(addressProductKey);
                if (DataValidateUtil.verifyInteger(productNum)){
                    productNum  = productNum + payOrderItemVo.getItemProductNum();
                    productAddressMap.put(addressProductKey, productNum);
                }else {
                    productAddressMap.put(addressProductKey, payOrderItemVo.getItemProductNum());
                }
            }
        }
        log.info("countPurchaseOrder 总地址产品个数 = {}", productMap.size());
        //2.2 插入产品地址统计值
        for (String productAddressKey : productAddressMap.keySet()){
            String[] productAddressArray = productAddressKey.split("_");
            Integer productNum = productAddressMap.get(productAddressKey);
            PurchaseTotalAddressInfo purchaseTotalAddressInfo = new PurchaseTotalAddressInfo();
            purchaseTotalAddressInfo.setGlobalControlId(recentProcession.getId());
            purchaseTotalAddressInfo.setRecordStatus(StatusEnum.EFFECTIVE_STATUS.getStatusCode());
            purchaseTotalAddressInfo.setPickAddressId(Long.parseLong(productAddressArray[0]));
            purchaseTotalAddressInfo.setProductId(Long.parseLong(productAddressArray[1]));
            purchaseTotalAddressInfo.setNeedTransportNumber(productNum);
            purchaseTotalAddressInfo.setAlreadyTransportNumber(0);
            purchaseTotalAddressInfo.setCreateTime(new Date());
            purchaseTotalAddressInfo.setUpdateTime(new Date());
            purchaseTotalAddressInfoMapper.insert(purchaseTotalAddressInfo);
        }
        //3 为各个地址生成对应的状态跟踪值
        List<FoundationPickGoodsAddress> foundationPickGoodsAddresses = foundationPickGoodsAddressMapper.selectPickGoodsAddressList();
        for (FoundationPickGoodsAddress foundationPickGoodsAddress : foundationPickGoodsAddresses) {
            LogicTransportInfo logicTransportInfo = new LogicTransportInfo();
            logicTransportInfo.setGlobalControlId(recentProcession.getId());
            logicTransportInfo.setPickAddressId(foundationPickGoodsAddress.getId());
            logicTransportInfo.setRecordStatus((byte)1);
            logicTransportInfo.setCreateTime(new Date());
            logicTransportInfo.setUpdateTime(new Date());
            logicTransportInfoMapper.insert(logicTransportInfo);
        }
        log.info("[service] [OUT] countPurchaseOrder success ");
        return new BaseResult(ErrorCodeEnum.SUCCESS);
    }

    @Override
    public BaseResult countPurchasePrice() {
        GlobalProcessionControl recentProcession = globalProcessionControlMapper.getRecentProcession();
        log.info("[service] [IN] countPurchasePrice param : recentProcession = {}", recentProcession.toString());
        // 获取长途运费
        ConfigCommon configInfoByCode = configCommonMapper.getConfigInfoByCode(CommonConstant.TRANSPORT_COST);
        String transportCost = configInfoByCode.getConfigValue();
        BigDecimal transportCostPrice = new BigDecimal(transportCost);
        log.info("单位运费 = {}", transportCost);

        List<PurchaseDetailInfoVo> purchaseDetailInfoVos = purchaseDetailInfoMapper.selectPurchaseListWithGlobal(recentProcession.getId());
        List<PurchasePriceCount> purchasePriceCounts = new ArrayList<>();
        //1. 按照产品ID聚合
        Map<Long, List<PurchaseDetailInfoVo>> purchaseDetailMap = new HashMap<>();
        for (PurchaseDetailInfoVo purchaseDetailInfoVo : purchaseDetailInfoVos) {
            List<PurchaseDetailInfoVo> purchaseDetailInfo = purchaseDetailMap.get(purchaseDetailInfoVo.getProductId());
            if (purchaseDetailInfo == null ){
                purchaseDetailInfo = new ArrayList<>();
                purchaseDetailInfo.add(purchaseDetailInfoVo);
                purchaseDetailMap.put(purchaseDetailInfoVo.getProductId(), purchaseDetailInfo);
            }else {
                purchaseDetailInfo.add(purchaseDetailInfoVo);
            }
        }
        //2. 统计
        for (Long productId : purchaseDetailMap.keySet()) {
            List<PurchaseDetailInfoVo> purchaseDetailVos = purchaseDetailMap.get(productId);
            BigDecimal totalAmount = new BigDecimal(0);
            Integer totalPurchaseNumber = 0;
            for (PurchaseDetailInfoVo purchaseDetailVo : purchaseDetailVos) {
                BigDecimal purchasePrice = purchaseDetailVo.getPurchasePrice();
                Integer purchaseNumber = purchaseDetailVo.getPurchaseNumber();
                totalAmount = totalAmount.add(purchasePrice.multiply(new BigDecimal(purchaseNumber)));
                totalPurchaseNumber += purchaseNumber;
            }
            BigDecimal averagePrice = totalAmount.divide(new BigDecimal(totalPurchaseNumber)); //加权平均价格

            BigDecimal purchaseAddTransportPrice = averagePrice.add(transportCostPrice); //价格+长途运输费用
            BigDecimal purchaseProfit = purchaseAddTransportPrice.multiply((new BigDecimal(0.05)));
            BigDecimal purchaseProfitAfter = BusinessUtil.calculateMoney(purchaseProfit);//利润
            BigDecimal userPickAddressPrice = purchaseAddTransportPrice.add(purchaseProfitAfter);//用户实际应支付单价
            log.info("加权平均价格 = {}, 利润 = {}, 用户实际应支付单价 = {}", averagePrice, purchaseProfitAfter, userPickAddressPrice);
            PurchasePriceCount purchasePriceCount = new PurchasePriceCount();
            purchasePriceCount.setGlobalControlId(recentProcession.getId());
            purchasePriceCount.setRecordStatus(StatusEnum.EFFECTIVE_STATUS.getStatusCode());
            purchasePriceCount.setProductId(productId);

            purchasePriceCount.setPurchasePriceAverage(averagePrice);
            purchasePriceCount.setPurchaseNum(totalPurchaseNumber);
            purchasePriceCount.setPurchasePricePickAddress(userPickAddressPrice);
            purchasePriceCount.setPurchaseProfit(purchaseProfitAfter);
            purchasePriceCount.setTransportFeeTheory(transportCostPrice);
            purchasePriceCount.setTransportFeeActual(new BigDecimal("0"));
            purchasePriceCount.setCreateTime(new Date());
            purchasePriceCount.setUpdateTime(new Date());
            purchasePriceCountMapper.insert(purchasePriceCount);
        }
        log.info("[service] [OUT] countPurchasePrice success ");

        return new BaseResult(ErrorCodeEnum.SUCCESS);
    }

    @Override
    public BaseResult addPurchaseDetail(String userId,
                                        Long purchaseTotalInfoId,
                                        String supplierName,
                                        String purchasePrice,
                                        Integer purchaseNumber) {
        GlobalProcessionControl recentProcession = globalProcessionControlMapper.getRecentProcession();
        log.info("[service] [IN] updatePurchaseDetail param : userId = {}, supplierName = {}, purchasePrice = {}, purchaseNumber = {}, recentProcession = {}",
                userId, supplierName, purchasePrice, purchaseNumber, recentProcession.toString());
        PurchaseTotalInfo purchaseTotalInfo = purchaseTotalInfoMapper.selectByPrimaryKey(purchaseTotalInfoId);
        Integer alreadyPurchaseNumber = purchaseTotalInfo.getAlreadyPurchaseNumber();
        //1. 添加新的采购明细
        PurchaseDetailInfo purchaseDetailInfo = new PurchaseDetailInfo();
        purchaseDetailInfo.setGlobalControlId(purchaseTotalInfo.getGlobalControlId());
        purchaseDetailInfo.setPurchaseTotalInfoId(purchaseTotalInfoId);
        purchaseDetailInfo.setProductId(purchaseTotalInfo.getProductId());
        purchaseDetailInfo.setRecordStatus(StatusEnum.EFFECTIVE_STATUS.getStatusCode());
        purchaseDetailInfo.setPurchaser(userId);
        purchaseDetailInfo.setSupplierName(supplierName);
        purchaseDetailInfo.setPurchasePrice(new BigDecimal(purchasePrice));
        purchaseDetailInfo.setPurchaseNumber(purchaseNumber);
        purchaseDetailInfo.setCreateTime(new Date());
        purchaseDetailInfo.setUpdateTime(new Date());
        purchaseDetailInfoMapper.insert(purchaseDetailInfo);
        //2. 变更统计值
        purchaseTotalInfo.setAlreadyPurchaseNumber(purchaseTotalInfo.getAlreadyPurchaseNumber() + purchaseNumber);
        log.info("统计值变更前 = {}, 统计值变更后 = {}, 变更数量 = {}", alreadyPurchaseNumber, purchaseTotalInfo.getAlreadyPurchaseNumber(), purchaseNumber);
        purchaseTotalInfoMapper.updateByPrimaryKeySelective(purchaseTotalInfo);
        log.info("[service] [OUT] updatePurchaseDetail success ");
        return new BaseResult(ErrorCodeEnum.SUCCESS);
    }

    @Override
    public BaseResult selectPurchaseCountList( int page, int size) {
        log.info("[service] [IN] selectPurchaseCountList param :  page = {}, size = {}", page, size);
        GlobalProcessionControl recentProcession = globalProcessionControlMapper.getRecentProcession();
        PageHelper.startPage(page, size);
        List<PurchaseTotalInfoVo> purchaseTotalInfoVos = purchaseTotalInfoMapper.selectPurchaseList(recentProcession.getId());
        PageInfo<PurchaseTotalInfoVo> purchaseTotalInfoVoPageInfo = new PageInfo<>(purchaseTotalInfoVos);
        log.info("[service] [OUT] selectPurchaseCountList success ");
        return new BaseResult(purchaseTotalInfoVoPageInfo);
    }

    @Override
    public BaseResult selectPurchaseDetailList(Long purchaseTotalInfoId,int page, int size) {
        log.info("[service] [IN] selectPurchaseDetailList param : page = {}, size = {}", page, size);
        PageHelper.startPage(page, size);
        List<PurchaseDetailInfoVo> purchaseDetailInfos = purchaseDetailInfoMapper.selectPurchaseDetailList(purchaseTotalInfoId);
        PageInfo<PurchaseDetailInfoVo> purchaseDetailInfoVoPageInfo = new PageInfo<>(purchaseDetailInfos);
        for (PurchaseDetailInfoVo purchaseDetailInfoVo : purchaseDetailInfos){
            String purchaser = purchaseDetailInfoVo.getPurchaser();
            FoundationSysUser foundationSysUser = foundationSysUserMapper.selectByPrimaryKey(purchaser);
            purchaseDetailInfoVo.setPurchaseName(foundationSysUser.getUserName());
        }
        log.info("[service] [OUT] selectPurchaseDetailList success ");
        return new BaseResult(purchaseDetailInfoVoPageInfo);
    }
}
